package com.yvdelx.cyclowomen.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.yvdelx.R;
import com.yvdelx.cyclowomen.activity.adapter.GridCellAdapter;
import com.yvdelx.cyclowomen.activity.adapter.HeaderCalendarCellAdapter;
import com.yvdelx.cyclowomen.activity.listener.ChoiceCycleDialogListener;
import com.yvdelx.cyclowomen.mediation.CycleManagement;
import com.yvdelx.cyclowomen.object.Cycle;
import com.yvdelx.cyclowomen.utility.ActivityUtility;
import com.yvdelx.cyclowomen.utility.LogUtility;

import java.text.ParseException;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import static com.yvdelx.cyclowomen.utility.StringUtility.CST_BUNDLE;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_IS_MODIFICATION;

/**
 * Calendar activity display the calendar with cycles
 */
public class CalendarActivity extends Activity implements View.OnClickListener {

    // TODO : ajouter une option pour prendre en compte ou non un jour dans le calcul
    // TODO : Indiquer les jours où la possibilité bébé est très forte
    // TODO : Implémenter la compatibilité Dafra
    // TODO : Implémenter le partage dropbox/drive/box

    private TextView currentMonth;
    private GridView calendarView;
    private GridCellAdapter adapter;
    private Calendar mCalendar;
    private ImageView prevMonth, nextMonth;
    private int month, year;
    private static final String dateTemplate = "MMMM yyyy";
    private Button graphButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calendar);

        ActivityUtility.addActivity(this);

        try {
            Cycle cycle = CycleManagement.getCycleCurrent();

            // Get the current date
            mCalendar = Calendar.getInstance(Locale.getDefault());

            if (cycle != null) {
                mCalendar.setTime(CycleManagement.getCurrentDate());
            }

            month = mCalendar.get(Calendar.MONTH) + 1;
            year = mCalendar.get(Calendar.YEAR);

            // Preparing the view
            graphButton = (Button) this.findViewById(R.id.selectedDayMonthYear);
            graphButton.setText(getResources().getString(R.string.button_graph));
            graphButton.setOnClickListener(this);

            prevMonth = (ImageView) this.findViewById(R.id.prevMonth);
            prevMonth.setOnClickListener(this);

            currentMonth = (TextView) this.findViewById(R.id.currentMonth);
            currentMonth.setText(DateFormat.format(dateTemplate, mCalendar.getTime()));

            nextMonth = (ImageView) this.findViewById(R.id.nextMonth);
            nextMonth.setOnClickListener(this);

            calendarView = (GridView) this.findViewById(R.id.calendar);

            // Initialised
            // Get the current cycle
            adapter = new GridCellAdapter(getApplicationContext(), month, year, this);

            adapter.notifyDataSetChanged();
            calendarView.setAdapter(adapter);

        } catch (ParseException e) {
            LogUtility.error(this.getClass(), e.getMessage(), e);
            this.finish();
        } catch (Exception e) {
            LogUtility.error(this.getClass(), e.getMessage(), e);
            this.finish();
        }

        // create the calendar headers
        GridView headerCalendarView = (GridView) this.findViewById(R.id.header_calendar);
        headerCalendarView.setAdapter(new HeaderCalendarCellAdapter(this));

    }

    /**
     * Update the calendar
     * @param month Integer
     * @param year Integer
     */
    private void setGridCellAdapterToDate(int month, int year) throws ParseException {

        adapter = new GridCellAdapter(getApplicationContext(), month, year, this);

        //noinspection MagicConstant,ResourceType
        mCalendar.set(year, (month - 1), mCalendar.get(Calendar.DAY_OF_MONTH));

        currentMonth.setText(DateFormat.format(dateTemplate, mCalendar.getTime()));
        adapter.notifyDataSetChanged();
        calendarView.setAdapter(adapter);
    }

    @Override
    public void onClick(View view) {
        // Determine witch view has been selected
        if (view == prevMonth) {
            if (month <= 1) {
                month = 12;
                year--;
            } else {
                month--;
            }
            draw();
        }
        if (view == nextMonth) {
            if (month > 11) {
                month = 1;
                year++;
            } else {
                month++;
            }
            draw();
        }
        if (view == graphButton) {
            List<Cycle> cycles = CycleManagement.getCycles(month,year);
            try{
                drawCycleChoiceDialog(cycles);
            } catch (Exception ex){
                LogUtility.error(this.getClass(),ex.getMessage(),ex);
                this.onBackPressed();
            }

        }
    }

    /**
     * This method display the cycle choice dialog if it's necessary.
     * @param cycles List<Cycle>
     */
    private void drawCycleChoiceDialog(List<Cycle> cycles) throws Exception {
        // Determine if the user needs the dialog
        switch (cycles.size()){
            // If no cycle, the graphic is not displayed
            case 0 :
                Toast.makeText(this,R.string.no_graphic,Toast.LENGTH_LONG).show();
                break;

            // If one cycle, it's displayed
            case 1 :
                Cycle cycle = cycles.get(0);
                this.displayGraphic(cycle);
                break;

            // If more one cycle, show the dialog
            default :
                CycleChoiceDialog dialog = new CycleChoiceDialog(cycles, this);
                ChoiceCycleDialogListener listener = new ChoiceCycleDialogListener(this);
                dialog.setOnDismissListener(listener);
                dialog.show();
                break;
        }
    }

    /**
     * This method start the graphic activity to draw the cycle in param
     * @param cycle Cycle
     */
    public void displayGraphic(Cycle cycle) throws Exception {
        // Set the current cycle : this is necessary for the graphic activity process
        CycleManagement.changeCurrentCycle(cycle);

        // Start the graphic activity
        Intent intent = new Intent(this.getApplicationContext(), GraphActivity.class);
        this.startActivity(intent);
    }

    /**
     * Call setGridCellAdapter
     */
    private void draw(){
        try {
            setGridCellAdapterToDate(month, year);
        } catch (ParseException e) {
            LogUtility.error(this.getClass(), e.getMessage(), e);
            this.finish();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.getApplication().onTerminate();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.calendar, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        // Find the selected item and realize the action
        switch(id){
            case R.id.modify_profile :
                Intent intent = new Intent(this.getApplicationContext(), ProfileActivity.class);
                Bundle bundle = new Bundle();
                bundle.putBoolean(CST_IS_MODIFICATION, true);
                intent.putExtra(CST_BUNDLE, bundle);
                this.startActivity(intent);
                break;

            case R.id.disclaimer :
                Context context = this.getApplicationContext();
                if (context != null){
                    Toast.makeText(context, R.string.disclaimer_value, Toast.LENGTH_LONG).show();
                }
                break;
        }

        return id == R.id.action_settings || super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        ActivityUtility.closeActivities();
    }


}